
package hk.ces.oxfam.patch.sql;

import hk.ces.oxfam.patch.connection.StatementFactory;
import hk.ces.oxfam.patch.result.BaseSQLResult;
import hk.ces.oxfam.patch.result.SQLResult;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

/**
 *
 * @author ReutyCheng
 */
public class QueryUtil
{
  private QueryUtil()
  {
  }
  
  public static SQLResult tablesAndColumns(Connection connection, String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern) throws SQLException
  {
    DatabaseMetaData metaData = connection.getMetaData();
    ResultSet resultSet = metaData.getColumns(catalog, schemaPattern, tableNamePattern, columnNamePattern);

    try
    {
      return new BaseSQLResult(resultSet, new PreparedSQL("list all tables and columns", new Object[]{}));
    }
    finally
    {
      StatementFactory.closeResource(resultSet);
    }
  }

  public static <T> T value(Connection connection, PreparedSQL preparedSQL, int resultsIndex, int columnIndex, Class<T> clazz) throws SQLException
  {
    return getResult(connection, preparedSQL).getValue(resultsIndex, columnIndex, clazz);
  }

  public static Object[] results(Connection connection, PreparedSQL preparedSQL, int resultsIndex) throws SQLException
  {
    return getResult(connection, preparedSQL).getResultsValue(resultsIndex);
  }

  public static <T> List<T> column(Connection connection, PreparedSQL preparedSQL, int columnIndex, Class<T> clazz) throws SQLException
  {
    return getResult(connection, preparedSQL).getColumnValue(columnIndex, clazz);
  }

  public static SQLResult query(Connection connection, PreparedSQL preparedSQL) throws SQLException
  {
    return getResult(connection, preparedSQL);
  }

  private static SQLResult getResult(Connection connection, PreparedSQL preparedSQL) throws SQLException
  {
    PreparedStatement statement = StatementFactory.getPrepareStatement(connection, preparedSQL);
    ResultSet resultSet = statement.executeQuery();

    try
    {
      return new BaseSQLResult(resultSet, preparedSQL);
    }
    finally
    {
      StatementFactory.closeResource(statement, resultSet);
    }
  }
}
